import { FastifyReply } from 'fastify';
import React, { ComponentType } from 'react';
import { renderToString } from 'react-dom/server';
import { ErrorArgument } from '../types';
import { HtmlSSRError } from './errors';
import { NotFoundError } from './errors/NotFoundError';

const html5DocumentType = '<!DOCTYPE html>';

function renderString<T = any>(Inner: ComponentType, props: T) {
    return renderToString(<Inner {...props} />);
}

function errorRender(reply: FastifyReply, statusCode: number, htmlString: string) {
    reply.status(statusCode).header('Content-Type', 'text/html;charset=UTF-8');
    return htmlString;
}

function ssrErrorRender(error: ErrorArgument) {
    return errorRender(
        error.reply,
        500,
        renderString(HtmlSSRError, { isDev: error.isDev, error: error.exception }),
    );
}

function notFoundErrorRender(error: ErrorArgument) {
    return errorRender(error.reply, 404, renderString(NotFoundError, { error: error.exception }));
}

const ErrorRenderMapping: { [key: number]: (error: ErrorArgument) => string } = {
    404: notFoundErrorRender,
    500: ssrErrorRender,
};

function getErrorRenderMapping(statusCode: number) {
    return ErrorRenderMapping?.[statusCode] ?? ssrErrorRender;
}

export { ssrErrorRender, notFoundErrorRender, getErrorRenderMapping };
